import 'dart:collection';

import 'package:cli_spinner/cli_spinner.dart';
import 'package:dart_ping/dart_ping.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:yoyo_get_fast_mirror/i18n.dart';

Logger _logger = Logger();
final speedResult = lightGreen.wrap(GetfastmirroCommand.speedResult);

Future<List<Map<String, String>>> testMirroSpeed(
  List<String> mirrorList,
) async {
  final spinner =
      Spinner.type(GetfastmirroCommand.speedTest, SpinnerType.boxCircle)..start();
  final testResult = <Map<String, String>>[];
  final logMsg = StringBuffer()..write(speedResult);
  for (final element in mirrorList) {
    late final PingData pingRes;
    late final double time;
    try {
      pingRes = await Ping(Uri.parse(element).host, count: 1).stream.first;
      time = pingRes.response!.time!.inMicroseconds * 0.001;
      testResult.add({'url': element, 'time': time.toStringAsFixed(3)});
      logMsg.write('\n${time.toStringAsFixed(3)}ms \t$element');
    } catch (e) {
      testResult.add({'url': element, 'time': '99999999'});
      logMsg.write('\nTimeout \t$element');
    }
  }
  spinner.updateMessage('');
  // ignore: cascade_invocations
  spinner.stop();
  _logger.info(logMsg.toString());
  final resultMap = testResult.asMap();
  final Map<int, Map<String, String>> sortedResult = SplayTreeMap.from(
    resultMap,
    (key1, key2) => double.parse(resultMap[key1]!['time'] ?? '') >
            double.parse(resultMap[key2]!['time'] ?? '')
        ? 1
        : -1,
  );
  final sortedUrlListAndTime =
      sortedResult.entries.map((e) => e.value).toList();
  return sortedUrlListAndTime;
}
